package com.ibeeking.found.open.b.rest.service.impl;

import com.ibeeking.found.common.enums.marketing.CouponVerificationStatusEnum;
import com.ibeeking.found.common.response.ResponseCodeEnum;
import com.ibeeking.found.open.api.common.dto.ApiMemberInfoDTO;
import com.ibeeking.found.open.api.common.query.ApiMemberInfoQuery;
import com.ibeeking.found.open.api.common.query.MemberIdCodeQuery;
import com.ibeeking.found.open.api.common.query.QrCodeQuery;
import com.ibeeking.found.open.api.common.query.ShopMemberCouponPageQuery;
import com.ibeeking.found.open.api.feign.MarketingFeignClient;
import com.ibeeking.found.open.api.feign.MemberFeignClient;
import com.ibeeking.found.open.b.rest.service.IMemberService;
import com.ibeeking.found.open.b.rest.service.ISystemService;
import com.ibeeking.found.open.service.common.dto.MemberCouponListDTO;
import com.ibeeking.found.open.service.common.dto.MemberInfoDTO;
import com.ibeeking.found.open.service.common.query.MemberCouponQuery;
import com.ibeeking.found.open.service.common.query.MemberInfoQuery;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.exception.DataNotExistException;
import com.ibeeking.nematos.utils.base.page.Page;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.DataUtils;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.result.ResponseResult;
import feign.Response;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;

import static java.math.BigDecimal.ROUND_UNNECESSARY;

/**
 * @ClassName MemberServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-06-04 11:45
 **/
@Service
public class MemberServiceImpl implements IMemberService {

    @Resource
    private MemberFeignClient memberFeignClient;
    @Resource
    private ISystemService systemServiceImpl;
    @Resource
    private MarketingFeignClient marketingFeignClient;

    @Override
    public MemberInfoDTO memberInfo(MemberInfoQuery query) {
        if (null == query.getMemberId() && StringUtils.isBlank(query.getMemberCode()) && StringUtils.isBlank(query.getMobile())) {
            throw new BusinessException(ResponseCodeEnum.PARAM_CHECK_FAIL.getCode(), ResponseCodeEnum.PARAM_CHECK_FAIL.getMsg());
        }
        Long memberId = query.getMemberId();
        if (null == memberId && StringUtils.isNotBlank(query.getMemberCode())) {
            MemberIdCodeQuery query1 = new MemberIdCodeQuery();
            query1.setMemberCode(query.getMemberCode());
            ResponseResult<Long> responseResult = memberFeignClient.queryAndCheckMemberIdByQrCode(query1);
            if (null == responseResult || null == responseResult.getData()) {
                return new MemberInfoDTO();
            }
            memberId = responseResult.getData();
        }
        ApiMemberInfoQuery query1 = new ApiMemberInfoQuery();
        query1.setMemberId(memberId);
        query1.setMobile(query.getMobile());
        ResponseResult<ApiMemberInfoDTO> responseResult = memberFeignClient.apiQueryMemberInfo(query1);
        if (null == responseResult || null == responseResult.getData()) {
            return new MemberInfoDTO();
        }
        return BeanUtil.convertBean(responseResult.getData(), MemberInfoDTO.class);
    }

    @Override
    public Page<MemberCouponListDTO> memberCouponList(MemberCouponQuery query) {
        ShopMemberCouponPageQuery shopMemberCouponPageQuery = BeanUtil.convertBean(query, ShopMemberCouponPageQuery.class);
        //查询会员id
        Long memberId = query.getMemberId();
        if (null == memberId && StringUtils.isNotBlank(query.getMemberCode())) {
            MemberIdCodeQuery query1 = new MemberIdCodeQuery();
            query1.setMemberCode(query.getMemberCode());
            ResponseResult<Long> responseResult = memberFeignClient.queryAndCheckMemberIdByQrCode(query1);
            if (null == responseResult || null == responseResult.getData()) {
                throw new DataNotExistException("会员不存在");
            }
            memberId = responseResult.getData();
        }
        shopMemberCouponPageQuery.setMemberId(memberId);
        shopMemberCouponPageQuery.setShopId(systemServiceImpl.queryShopIdByShopCode(query.getShopCode()));
        shopMemberCouponPageQuery.setCouponTypeCode(query.getCouponType());
        shopMemberCouponPageQuery.setVerification(CouponVerificationStatusEnum.VERIFICATION.getCode().equals(query.getVerification()));

        ResponseResult<Page<com.ibeeking.found.open.api.common.dto.MemberCouponListDTO>> pages = marketingFeignClient.shopMemberCouponList(shopMemberCouponPageQuery);

        if (!com.ibeeking.nematos.utils.result.ResponseCodeEnum.SUCCESS.getCode().equals(pages.getCode())) {
            return new Page<>();
        }
        com.ibeeking.nematos.utils.base.page.Page<MemberCouponListDTO> result = BeanUtil.convertBean(pages.getData(), com.ibeeking.nematos.utils.base.page.Page.class);
        List<MemberCouponListDTO> list = new ArrayList<>();
        pages.getData().getRecords().forEach(s -> {
            MemberCouponListDTO memberCouponListDTO = new MemberCouponListDTO();
            memberCouponListDTO.setPromotionId(s.getCouponId());
            memberCouponListDTO.setPromotionName(s.getCouponName());
            memberCouponListDTO.setCouponId(s.getCouponId());
            memberCouponListDTO.setCouponCode(s.getId());
            memberCouponListDTO.setName(s.getCouponName());
            memberCouponListDTO.setValidityStartTime(s.getStartTime());
            memberCouponListDTO.setValidityEndTime(s.getEndTime());
            memberCouponListDTO.setVerification(s.getVerificationStatus());
            Integer status = 1;
            if (2 == s.getVerificationStatus()) {
                status = 2;
            } else {
                if (1 != s.getCouponStatus()) {
                    status = 2;
                }
            }
            memberCouponListDTO.setStatus(status);
            memberCouponListDTO.setCouponType(s.getCouponTypeCode());
            memberCouponListDTO.setCouponTypeName(s.getCouponTypeName());
            memberCouponListDTO.setParValue(DataUtils.fromFenToYuan(s.getWorth(), 2, ROUND_UNNECESSARY));
            memberCouponListDTO.setCouponPic(s.getCouponPic());
            list.add(memberCouponListDTO);
        });
        result.setRecords(list);
        return result;
    }

    @Override
    public void qrCode(HttpServletResponse response, QrCodeQuery query) {
        try {
            Response response1 = memberFeignClient.memberQrCode(query);
            if (null != response1) {
                Response.Body body = response1.body();
                stream(body.asInputStream(), response.getOutputStream());
            }
        } catch (IOException e) {
            throw new BusinessException("会员码刷新失败，请重试");
        }
    }

    public static long stream(InputStream input, OutputStream output) throws IOException {
        try (
                ReadableByteChannel inputChannel = Channels.newChannel(input);
                WritableByteChannel outputChannel = Channels.newChannel(output);
        ) {
            ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
            long size = 0;

            while (inputChannel.read(buffer) != -1) {
                buffer.flip();
                size += outputChannel.write(buffer);
                buffer.clear();
            }
            return size;
        }
    }
}
